#include <Arduino.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
#include <Hash.h>
#include "api_client.h"

int lastOnlineTime = 0;
int lastBoardTime = 0;

int ApiClient::get_timestamp(){
    int curBoardTime = millis()/1000;
    if((lastOnlineTime != 0)
        && (nonce % 100 != 0)){ // 99%的情况下 都用缓存的时间
        return (curBoardTime - lastBoardTime) + lastOnlineTime;
    }
    String api = "http://" + server + "/public/get_time";
    String timestamp;
    if(http_get(api, timestamp) != 0){
        Serial.println("get_timestamp fail");
        return -1;
    }
    Serial.println("timestamp=" + timestamp);
    int now = timestamp.toInt();
    curBoardTime = millis()/1000;
    lastOnlineTime = now;
    lastBoardTime = curBoardTime;
    return now;
}

ApiClient::ApiClient(String server, String clientId, String token){
    this->server = server;
    this->token = token;
    this->clientId = clientId;
}

int ApiClient::http_get(String url, String& resp) {
  HTTPClient http;
  http.setTimeout(1000*60);    // 60s timeout
  Serial.printf("[HTTP] GET %s\n", url.c_str());
  http.begin(url);
  int httpCode = http.GET();
  if (httpCode <= 0) {
    Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
    return -1;
  }
  Serial.printf("[HTTP] GET... code: %d\n", httpCode);
  // file found at server
  if (httpCode == HTTP_CODE_OK) {
    String payload = http.getString();
    resp = payload;
  }
  http.end();
  return 0;
}


int ApiClient::request_api(String api, String ext_data, String& value){
    String timestamp(get_timestamp());
    api += "?timestamp=" + timestamp;
    String nonceStr(nonce++);
    api += "&nonce=" + nonceStr;
    if(ext_data.length() > 0){
        api += ext_data;
    }
    api += "&clientId=" + clientId;

    Serial.println(api + "#" + token);
    String sign = sha1(api + "#" + token);
    api += "&sign=" + sign;
    api = "http://" + server + api;
    String resp;
    if(http_get(api, resp) != 0){
        return -1;
    }
    Serial.println("[HTTP] resp=" + resp);
    DynamicJsonBuffer jsonBuffer;
    JsonObject& resp_json = jsonBuffer.parseObject(resp);
    int code = resp_json["code"];
    int msg = resp_json["code"];
    if(code != 0){
        Serial.println("resp code error, code=" + String(code) + " msg=" + msg);
        return -2;
    }
    value = resp_json["value"].as<String>();
    return 0;
}

int ApiClient::sync_data(String& value, int humi, int temp) {
    String path = "/client/sync_data";
    String ext_data = "&humi=" + String(humi);
    ext_data += "&temp=" + String(temp);
    if(request_api(path, ext_data, value) != 0){
        return -1;
    }
    Serial.println("sync_data value=" + value);
    return 0;
}
